package com.example.check.service;

import com.example.common.ThisSystemException;
import static com.example.common.AssertThrowUtil.*;
import com.example.check.mapper.UserMapper;
import com.example.check.entity.UserEntity;
import com.example.common.GetPassWord;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

/**
 * Created by 13296 on 2017/7/13.
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper udao;
    private final Log log = LogFactory.getLog(getClass());
    @Override
    public UserEntity login(String account, String password, Subject subject) throws Exception{
        account =$("账户不能为空！",account);
        password = $("密码不能为空！",password);
        UserEntity u = null;

        u = udao.select("account",account);
        if (u==null){
            throw new ThisSystemException("账户不存在！");
        }

        String algorithmName = "md5";
        String salt1 = u.getAccount();
        String salt2 = u.getRandomSalt();
        int hashIterations = 2;
        SimpleHash testHash = new SimpleHash(algorithmName, password, salt1 + salt2, hashIterations);
        String testPassword = testHash.toHex();


        log.info("用户输入后的加密密码" + testPassword + "\n");
        log.info("数据库里的随机数盐"+ salt2 + "\n");

        UsernamePasswordToken token = new UsernamePasswordToken(account, testPassword);

        try{
            //shiro验证登录用户
            subject.login(token);
        }catch (AuthenticationException e){
            throw new ThisSystemException("密码错误！");
        }
        return u;
    }

    @Override
    public ArrayList<UserEntity> searchAllUser() throws Exception {
        return udao.selectAllUser();
    }

    @Override
    public UserEntity updatePassword(int id,String oldPassword, String newPassword, String newPasswordConfirm) throws Exception {
        //1.验证参数
        oldPassword = $("旧密码必须填写！",oldPassword);
        newPassword = $("新密码必须填写！",newPassword);
        newPasswordConfirm = $("新密码确认必须填写！",newPasswordConfirm);
        assertEquals("两次密码不一致",newPassword,newPasswordConfirm);
        assertNotEquals("新密码和旧密码不能一样",oldPassword,newPassword);
        //2.找到用户
        UserEntity u = udao.select("id",id);
        /*
        if(id==null){
            throw  new ThisSystemException("无法找到这个用户！");
        }*/
        assertNotNull("无法找到这个用户",u);

        //3/验证旧密码
        //加密密码，利用“帐户名+随机数”来做密码的盐，以保证即使两个相同密码的加密字段也不相同
        //其中，随机数将当成数据库中用户表的内容之一，在shiro验证环节中被取出验证
        //具体散列算法是：md5(md5(密码+username+salt2))）
        String algorithmName = "md5";
        String salt1 = u.getAccount();
        String salt2 = u.getRandomSalt();
        int hashIterations = 2;
        SimpleHash testHash = new SimpleHash(algorithmName, oldPassword, salt1 + salt2, hashIterations);
        String testPassword = testHash.toHex();

        assertTrue("旧密码不正确！", testPassword.equals(u.getPassword()));

        //4.加密密码验证正确，进行更新密码操作
        //新的随机数盐，将在数据库更新
        String newSalt = new SecureRandomNumberGenerator().nextBytes().toHex();
        SimpleHash newHash = new SimpleHash(algorithmName, newPassword, salt1 + newSalt, hashIterations);
        String finalPassword = newHash.toHex();
        u.setPassword(finalPassword);
        u.setRandomSalt(newSalt);

        udao.update(u);

        return u;
    }

    @Override
    public UserEntity enroll(String account, String password, String name, String roleLevel, String sex, String telephone, String email, String address) throws Exception {
        //验证ID、账户、密码、名字不能为空

        account =$("账户不能为空！",account);
        password = $("密码不能为空！",password);
        name=$("名字不能为空",name);
        ArrayList<UserEntity> userList = searchAllUser();
        for(UserEntity u : userList){
            if(account.equals(u.getAccount())){
                throw new Exception("存在重复账户，请更改账户");
            }

        }
        //验证ID、账户、唯一

        //加密密码，利用“帐户名+随机数”来做密码的盐，以保证即使两个相同密码的加密字段也不相同
        //其中，随机数将当成数据库中用户表的内容之一，在shiro验证环节中被取出验证
        //具体散列算法是：md5(md5(密码+username+salt2))）
        String algorithmName = "md5";
        String salt1 = account;
        String salt2 = new SecureRandomNumberGenerator().nextBytes().toHex();
        int hashIterations = 2;
        SimpleHash hash = new SimpleHash(algorithmName, password, salt1 + salt2, hashIterations);
        String finalPassword = hash.toHex();


        UserEntity u = new UserEntity(account,finalPassword,salt2,name,roleLevel,sex,telephone,email,address);

        udao.insertUser(u);
        return null;
    }

    @Override
    public UserEntity SearchUserByID(int id) throws Exception {
        UserEntity result = udao.selectUserByID(id);
        if (result == null){
            throw new ThisSystemException("未查到用户！");
        }
        return result;
    }

    @Override
    public void deleteUserById(int id) throws Exception {
        udao.deleteUserById(id);
        return ;
    }

    @Override
    public void editUser(UserEntity user) throws Exception {
        UserEntity u = udao.select("id",user.getId());
        assertNotNull("无法找到这个用户",u);
        udao.editUser(user);
        return ;
    }

    @Override
    public ArrayList<UserEntity> SearchUserByField(String field, String code) throws Exception {
//        field =$("查找域不能为空",field);
//        code =$("关键词不能为空！",code);
        ArrayList<UserEntity> result = null;
        result = udao.selectUserByField(field,code);
        if (result == null){
            throw new ThisSystemException("未查到关键词！");
        }
        return result;
    }

    @Override
    public ArrayList<UserEntity> SearchUserLikeByField(String field, String code) throws Exception {
        ArrayList<UserEntity> result = null;
        result = udao.selectUserLikeByField(field,code);
        if (result == null){
            throw new ThisSystemException("未查到关键词！");
        }
        return result;
    }

    @Override
    public void giveUserRole(int id, String role) throws Exception {
        udao.giveUserRole(id,role);
        return ;
    }

}
